package v1alpha1

import (
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

const (
	VulnerabilityReportsCRName    = "vulnerabilityreports.aquasecurity.github.io"
	VulnerabilityReportsCRVersion = "v1alpha1"
	VulnerabilityReportKind       = "VulnerabilityReport"
	VulnerabilityReportListKind   = "VulnerabilityReportList"

	ClusterVulnerabilityReportsCRName = "clustervulnerabilityreports.aquasecurity.github.io"
)

// VulnerabilitySummary is a summary of Vulnerability counts grouped by Severity.
type VulnerabilitySummary struct {
	// CriticalCount is the number of vulnerabilities with Critical Severity.
	CriticalCount int `json:"criticalCount"`

	// HighCount is the number of vulnerabilities with High Severity.
	HighCount int `json:"highCount"`

	// MediumCount is the number of vulnerabilities with Medium Severity.
	MediumCount int `json:"mediumCount"`

	// LowCount is the number of vulnerabilities with Low Severity.
	LowCount int `json:"lowCount"`

	// UnknownCount is the number of vulnerabilities with unknown severity.
	UnknownCount int `json:"unknownCount"`

	// NoneCount is the number of packages without any vulnerability.
	NoneCount int `json:"noneCount"`
}

// Registry is a collection of repositories used to store Artifacts.
type Registry struct {
	// Server the FQDN of registry server.
	Server string `json:"server"`
}

// Artifact represents a standalone, executable package of software that
// includes everything needed to run an application.
type Artifact struct {
	// Repository is the name of the repository in the Artifact registry.
	Repository string `json:"repository"`

	// Digest is a unique and immutable identifier of an Artifact.
	Digest string `json:"digest,omitempty"`

	// Tag is a mutable, human-readable string used to identify an Artifact.
	Tag string `json:"tag,omitempty"`

	// MimeType represents a type and format of an Artifact.
	MimeType string `json:"mimeType,omitempty"`
}

// Vulnerability is the spec for a vulnerability record.
type Vulnerability struct {
	// VulnerabilityID the vulnerability identifier.
	VulnerabilityID string `json:"vulnerabilityID"`

	// Resource is a vulnerable package, application, or library.
	Resource string `json:"resource"`

	// InstalledVersion indicates the installed version of the Resource.
	InstalledVersion string `json:"installedVersion"`

	// FixedVersion indicates the version of the Resource in which this vulnerability has been fixed.
	FixedVersion string `json:"fixedVersion"`

	Severity    Severity `json:"severity"`
	Title       string   `json:"title"`
	Description string   `json:"description,omitempty"`
	PrimaryLink string   `json:"primaryLink,omitempty"`
	Links       []string `json:"links"`
	Score       *float64 `json:"score,omitempty"`
}

// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// VulnerabilityReport is a specification for the VulnerabilityReport resource.
type VulnerabilityReport struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata,omitempty"`

	// Report is the actual vulnerability report data.
	Report VulnerabilityReportData `json:"report"`
}

// VulnerabilityReportData is the spec for the vulnerability scan result.
//
// The spec follows the Pluggable Scanners API defined for Harbor.
// @see https://github.com/goharbor/pluggable-scanner-spec/blob/master/api/spec/scanner-adapter-openapi-v1.0.yaml
type VulnerabilityReportData struct {
	// UpdateTimestamp is a timestamp representing the server time in UTC when this report was updated.
	UpdateTimestamp metav1.Time `json:"updateTimestamp"`

	// Scanner is the scanner that generated this report.
	Scanner Scanner `json:"scanner"`

	// Registry is the registry the Artifact was pulled from.
	Registry Registry `json:"registry"`

	// Artifact is a container image scanned for Vulnerabilities.
	Artifact Artifact `json:"artifact"`

	// Summary is a summary of Vulnerability counts grouped by Severity.
	Summary VulnerabilitySummary `json:"summary"`

	// Vulnerabilities is a list of operating system (OS) or application software Vulnerability items found in the Artifact.
	Vulnerabilities []Vulnerability `json:"vulnerabilities"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// VulnerabilityReportList is a list of VulnerabilityReport resources.
type VulnerabilityReportList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata"`

	Items []VulnerabilityReport `json:"items"`
}

// +genclient
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// ClusterVulnerabilityReport is a specification for the ClusterVulnerabilityReport resource.
type ClusterVulnerabilityReport struct {
	metav1.TypeMeta   `json:",incline"`
	metav1.ObjectMeta `json:"metadata,omitempty"`

	Report VulnerabilityReportData `json:"report"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// ClusterVulnerabilityReportList is a list of ClusterVulnerabilityReport resources.
type ClusterVulnerabilityReportList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata"`

	Items []ClusterVulnerabilityReport `json:"items"`
}
